﻿//----------------------------------------------------------------
// Desc: 
// Edit: koiey
//
// Date Created: 2011-10-15
//
// Update Date : 
//
// Copyright (c) Fuel4D (http://www.fuel4d.com), All rights reserved.
//
//----------------------------------------------------------------
#pragma once


#if FUEL_OS_WINDOWS


//----------------------------------------------------------------
//
//----------------------------------------------------------------
// 自定义定时器回调函数
typedef void (FCALL *FNET_TIMER_CALLBACK)(DWORD dwEventIndex);
// 创建新的连接时回调函数
typedef void (FCALL *FNET_ACCEPT_CALLBACK)(DWORD dwConnectionIndex);
// 收到新消息时回调函数
typedef void (FCALL *FNET_RECV_CALLBACK)(DWORD dwConnectionIndex,ACHAR* pMsg,DWORD dwLength);
// 关闭连接时回调函数
typedef void (FCALL *FNET_DISCONNECT_CALLBACK)(DWORD dwConnectionIndex);
// 连接某个IP和端口成功时回调函数
typedef void (FCALL *FNET_CONNECT_SUCCESS_CALLBACK)(DWORD dwConnectionIndex,void* pVoid);
// 连接某个IP和端口失败时回调函数
typedef void (FCALL *FNET_CONNECT_FAIL_CALLBACK)(void* pVoid);


//----------------------------------------------------------------
//
//----------------------------------------------------------------
struct FTimerEvent
{
    DWORD dwPeriodicTime;           // 事件触发间隔，毫秒
    FNET_TIMER_CALLBACK pEventFunc; // 事件处理函数地址

    FTimerEvent()
    {
        dwPeriodicTime = 0;
        pEventFunc = 0;
    }
};


//----------------------------------------------------------------
//
//----------------------------------------------------------------
struct FNetParameter
{
    // “用户端”和“服务端”仅表示两种连接模式，不是真正意思上的服务器与客户端
    // “用户端”没有监听能力，而“服务端”具有监听能力
    // 两种种模式下可以连接多个端口，连接成功以后返回该端口的连接索引“dwConnectionIndex”，也就是连接线路

    DWORD dwMaxUserNum;                     // 最大“用户端”连接数量
    FNET_RECV_CALLBACK OnRecvFromUserTCP;   // 收到“用户端”消息时的回调函数
    FNET_ACCEPT_CALLBACK OnAcceptUser;      // 有新的“用户端”连接请求时回调函数
    FNET_DISCONNECT_CALLBACK OnDisconnectUser;// “用户端”断开连接时回调函数
    DWORD dwUserMaxTransferSize;            // “用户端”单个消息的最大尺寸
    DWORD dwUserBufferSizePerConnection;    // “用户端”数据缓存最大尺寸

    DWORD dwMaxServerNum;                   // 最大“服务端”连接数量
    FNET_RECV_CALLBACK OnRecvFromServerTCP; // 收到“服务端”消息时的回调函数
    FNET_ACCEPT_CALLBACK OnAcceptServer;    // 有新的“服务端”连接请求时回调函数
    FNET_DISCONNECT_CALLBACK OnDisconnectServer;// “服务端”断开连接时回调函数
    DWORD dwServerMaxTransferSize;          // “服务端”单个消息的最大尺寸
    DWORD dwServerBufferSizePerConnection;  // “服务端”数据缓存最大尺寸

    DWORD dwMainMsgQueMaxBufferSize;
    DWORD dwConnectNumAtSameTime;
    DWORD dwFlag;

    DWORD dwCustomDefineEventNum;
    FTimerEvent pEvent[eNCD_MaxTimerEvent]; // 定时回调函数表

    FNetParameter()
    {
        FMemzero(this, sizeof(*this) - sizeof(pEvent));
    }
};


//----------------------------------------------------------------
//
//----------------------------------------------------------------
struct FNetPacketList
{
    ACHAR* pMsg;
    DWORD dwLen;
    FNetPacketList*	pNext;
    DWORD dwFlag;
};


//----------------------------------------------------------------
//
//----------------------------------------------------------------
class IFNetwork : public IFMemObject
{
protected:
    explicit IFNetwork(){}

public:
    // 创建网络模块环境
    virtual bool FCALL CreateNetwork(FNetParameter& desc,DWORD dwUserAcceptInterval,DWORD dwServerAcceptInterval) = 0;
    // 消毁网络模块环境
    virtual void FCALL Destroy() = 0;
    // 暂停网络模块主线程
    virtual void FCALL BreakMainThread() = 0;
    // 恢复网络模块主线程
    virtual void FCALL ResumeMainThread() = 0;

    // 设置“用户端”指定的连接线路用户数据
    virtual void FCALL SetUserInfo(DWORD dwConnectionIndex,void* user) = 0;
    // 获取“用户端”指定的连接线路用户数据
    virtual void* FCALL GetUserInfo(DWORD dwConnectionIndex) = 0;
    // 设置“服务端”指定的连接线路用户数据
    virtual void FCALL SetServerInfo(DWORD dwConnectionIndex,void* server) = 0;
    // 获取“服务端”指定的连接线路用户数据
    virtual void* FCALL GetServerInfo(DWORD dwConnectionIndex) = 0;

    // 获取“服务端”指定的线路的socket信息
    virtual sockaddr_in* FCALL GetServerAddress(DWORD dwConnectionIndex) = 0;
    // 获取“用户端”指定的线路的socket信息
    virtual sockaddr_in* FCALL GetUserAddress(DWORD dwConnectionIndex) = 0;
    // 获取“服务端”指定的线路的IP地址和端口
    virtual bool FCALL GetServerAddress(DWORD dwConnectionIndex,ACHAR* pIP,WORD* pwPort) = 0;
    // 获取“用户端”指定的线路的IP地址和端口
    virtual bool FCALL GetUserAddress(DWORD dwConnectionIndex,ACHAR* pIP,WORD* pwPort) = 0;
    // 通过“服务端”指定的线路发送数据
    virtual bool FCALL SendToServer(DWORD dwConnectionIndex,ACHAR* msg,DWORD length,DWORD flag) = 0;
    // 通过“用户端”指定的线路发送数据
    virtual bool FCALL SendToUser(DWORD dwConnectionIndex,ACHAR* msg,DWORD length,DWORD flag) = 0;
    // 强制断开“服务端”指定的线路
    virtual void FCALL CompulsiveDisconnectServer(DWORD dwConnectionIndex) = 0;
    // 强制断开“用户端”指定的线路
    virtual void FCALL CompulsiveDisconnectUser(DWORD dwConnectionIndex) = 0;
    virtual int FCALL GetServerMaxTransferRecvSize() = 0;
    virtual int FCALL GetServerMaxTransferSendSize() = 0;
    virtual int FCALL GetUserMaxTransferRecvSize() = 0;
    virtual int FCALL GetUserMaxTransferSendSize() = 0;
    // 给“服务端”所有线路广播消息
    virtual void FCALL BroadcastServer(ACHAR* pMsg,DWORD len,DWORD flag) = 0;
    // 给“用户端”所有线路广播消息
    virtual void FCALL BroadcastUser(ACHAR* pMsg,DWORD len,DWORD flag) = 0;
    virtual DWORD FCALL GetConnectedServerNum() = 0;
    virtual DWORD FCALL GetConnectedUserNum() = 0;
    virtual WORD FCALL GetBindedPortServerSide() = 0;
    virtual WORD FCALL GetBindedPortUserSide() = 0;
    virtual bool FCALL ConnectToServerWithUserSide(const ACHAR* szIP,WORD port,FNET_CONNECT_SUCCESS_CALLBACK,FNET_CONNECT_FAIL_CALLBACK,void* pExt) = 0;
    virtual bool FCALL ConnectToServerWithServerSide(const ACHAR* szIP,WORD port,FNET_CONNECT_SUCCESS_CALLBACK,FNET_CONNECT_FAIL_CALLBACK,void* pExt) = 0;	
    // 启动“用户端”服务器
    virtual bool FCALL StartServerWithUserSide(ACHAR* ip,WORD port) = 0;
    // 启动“服务端”服务器
    virtual bool FCALL StartServerWithServerSide(ACHAR* ip,WORD port) = 0;
    // 取得指定时钟的事件句柄，以便于
    virtual HANDLE FCALL GetCustomEventHandle(DWORD index) = 0;
    // 暂停指定编号时钟
    virtual	bool FCALL PauseTimer(DWORD dwCustomEventIndex) = 0;
    // 恢复指定编号时钟
    virtual	bool FCALL ResumeTimer(DWORD dwCustomEventIndex) = 0;

    virtual bool FCALL SendToServer(DWORD dwConnectionIndex,WSABUF* pBuf,DWORD dwNum,DWORD flag) = 0;	
    virtual bool FCALL SendToUser(DWORD dwConnectionIndex,WSABUF* pBuf,DWORD dwNum,DWORD flag) = 0;	
    virtual bool FCALL SendToServer(DWORD dwConnectionIndex,FNetPacketList* pList,DWORD flag) = 0;
    virtual bool FCALL SendToUser(DWORD dwConnectionIndex,FNetPacketList* pList,DWORD flag) = 0;
};


extern FAPI IFNetwork* FNewNetwork(FNEW_FUNC_API);


#endif